package rpg.player;

import java.awt.Cursor;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;

import launch.Launch;
import rpg.action.Skill;
import rpg.map.Creature;
import rpg.map.Location;
import rpg.map.MapObject;
import rpg.visual.VisualImage;
import square.data.MapObjectData;

public class Player {
	private Creature creature;
	private PlayerSlot head = new PlayerSlot("head");
	private PlayerSlot neck = new PlayerSlot("neck");
	private PlayerSlot back = new PlayerSlot("back");
	private PlayerSlot body = new PlayerSlot("body");
	private PlayerSlot leftHand = new PlayerSlot("leftHand");
	private PlayerSlot rightHand = new PlayerSlot("rightHand");
	private PlayerSlot leftFinger = new PlayerSlot("leftFinger");
	private PlayerSlot rightFinger = new PlayerSlot("rightFinger");
	private PlayerSlot legs = new PlayerSlot("legs");
	private PlayerSlot foots = new PlayerSlot("foots");
	private Double lastTranslateX, lastTranslateY;

	private Skill skillCast = null;

	// Movement Variables
	private Object nextMovement = null;

	// Creation
	public Player(Creature creature) {
		this.setCreature(creature);
	}

	// Skill
	public void cast(Skill skill) {
		if (!skill.available())
			return;

		if (skill.getData().getTarget() == false || skill.getData().getTarget()
				&& getCreature().getTarget() != null) {
			skill.onUse(getCreature().getTarget());
		} else {
			Launch.getLauncher().getMainComponent()
					.setCursor(Cursor.CROSSHAIR_CURSOR);
			Launch.getLauncher().getMainComponent().getMap().mouseLock(true);
			setSkillCast(skill);
		}
	}

	// Event Response
	public void walk() {
		if (nextMovement == null || getCreature().getWalkStart() != 0L)
			return;

		if (nextMovement.getClass() == Integer.class) {
			getCreature().setSide((int) nextMovement);
			getCreature().walk();
			nextMovement = null;
		} else {
			getCreature().walkTo((Location) nextMovement, false);
		}
	}

	// Live Events
	public void onDie() {
		System.out.println("Player die.");
		System.exit(0);
	}

	// Input Events
	public void onKeyPress(KeyEvent event) {
		switch (event.getKeyCode()) {
		// Move
		case KeyEvent.VK_RIGHT:
		case KeyEvent.VK_NUMPAD6:
			nextMovement = MapObjectData.SIDE_RIGHT;
			break;
		case KeyEvent.VK_LEFT:
		case KeyEvent.VK_NUMPAD4:
			nextMovement = MapObjectData.SIDE_LEFT;
			break;
		case KeyEvent.VK_UP:
		case KeyEvent.VK_NUMPAD8:
			nextMovement = MapObjectData.SIDE_UP;
			break;
		case KeyEvent.VK_DOWN:
		case KeyEvent.VK_NUMPAD2:
			nextMovement = MapObjectData.SIDE_DOWN;
			break;
		case KeyEvent.VK_NUMPAD3:
			nextMovement = MapObjectData.SIDE_RIGHT_DOWN;
			break;
		case KeyEvent.VK_NUMPAD1:
			nextMovement = MapObjectData.SIDE_LEFT_DOWN;
		case KeyEvent.VK_NUMPAD7:
			nextMovement = MapObjectData.SIDE_LEFT_UP;
			break;
		case KeyEvent.VK_NUMPAD9:
			nextMovement = MapObjectData.SIDE_RIGHT_UP;
			break;
		case KeyEvent.VK_NUMPAD5:
			nextMovement = null;
			break;
		// Skills
		case KeyEvent.VK_1:
			Launch.getLauncher().getMainComponent().getMenu().getSkills()
					.get(0).castSkill();
			break;
		case KeyEvent.VK_2:
			Launch.getLauncher().getMainComponent().getMenu().getSkills()
					.get(1).castSkill();
			break;
		}
		walk();
	}

	public void onMouseClick(MouseEvent event) {
		Double x = event.getX() + getLastTranslateX();
		Double y = event.getY() + getLastTranslateY();

		int squareX = (int) Math.floor(x / VisualImage.SQUARE_SIZE);
		int squareY = (int) Math.floor(y / VisualImage.SQUARE_SIZE);

		Location location = this
				.getCreature()
				.getMap()
				.getLocation(squareX, squareY,
						this.getCreature().getLocation().getZ());

		if (location == null)
			return;

		if (skillCast != null) {
			Launch.getLauncher().getMainComponent().getMap().mouseLock(false);
			Launch.getLauncher().getMainComponent()
					.setCursor(Cursor.DEFAULT_CURSOR);

			if (location.getCreature() != null) {
				getSkillCast().onUse(
						(MapObject) location.getCreature().getOwner());
				setSkillCast(null);
			} else if (location.getItems().size() > 0) {
				getSkillCast().onUse(
						(MapObject) location.getItems().get(0).getOwner());
				setSkillCast(null);
			}
		} else {
			if (event.getButton() == MouseEvent.BUTTON1) {
				nextMovement = location;
				walk();
			} else if (event.getButton() == MouseEvent.BUTTON3) {
				Creature creature = (Creature) (location.getCreature() == null ? location
						.getMovingCreature() : location.getCreature().getOwner());
				if (creature != null && creature != this.getCreature()) {
					if (creature == this.getCreature().getTarget()) {
						this.getCreature().onTarget(null);
					} else {
						this.getCreature().onTarget(creature);
					}
				}
			}
		}
	}

	// Creature Event
	public void onCreatureWalkFinish() {
		walk();
	}

	// Get & Set
	public Creature getCreature() {
		return creature;
	}

	public void setCreature(Creature creature) {
		this.creature = creature;
	}

	public PlayerSlot getHead() {
		return head;
	}

	public void setHead(PlayerSlot head) {
		this.head = head;
	}

	public PlayerSlot getNeck() {
		return neck;
	}

	public void setNeck(PlayerSlot neck) {
		this.neck = neck;
	}

	public PlayerSlot getBack() {
		return back;
	}

	public void setBack(PlayerSlot back) {
		this.back = back;
	}

	public PlayerSlot getBody() {
		return body;
	}

	public void setBody(PlayerSlot body) {
		this.body = body;
	}

	public PlayerSlot getLeftHand() {
		return leftHand;
	}

	public void setLeftHand(PlayerSlot leftHand) {
		this.leftHand = leftHand;
	}

	public PlayerSlot getRightHand() {
		return rightHand;
	}

	public void setRightHand(PlayerSlot rightHand) {
		this.rightHand = rightHand;
	}

	public PlayerSlot getLeftFinger() {
		return leftFinger;
	}

	public void setLeftFinger(PlayerSlot leftFinger) {
		this.leftFinger = leftFinger;
	}

	public PlayerSlot getRightFinger() {
		return rightFinger;
	}

	public void setRightFinger(PlayerSlot rightFinger) {
		this.rightFinger = rightFinger;
	}

	public PlayerSlot getLegs() {
		return legs;
	}

	public PlayerSlot getFoots() {
		return foots;
	}

	public Object getNextMovement() {
		return nextMovement;
	}

	public void setNextMovement(Object nextMovement) {
		this.nextMovement = nextMovement;
	}

	public Double getLastTranslateX() {
		return lastTranslateX;
	}

	public void setLastTranslateX(Double lastTranslateX) {
		this.lastTranslateX = lastTranslateX;
	}

	public Double getLastTranslateY() {
		return lastTranslateY;
	}

	public void setLastTranslateY(Double lastTranslateY) {
		this.lastTranslateY = lastTranslateY;
	}

	public Skill getSkillCast() {
		return skillCast;
	}

	public void setSkillCast(Skill skillCast) {
		this.skillCast = skillCast;
	}
}
